/**
 * URL QueryString 编解码
 * @author stone58@qq.com
 * --------------------------------
 * Usage:
 * [从字符串中提取字段]
 * 		var url = "api.diandao.org/get?id=101&name=baby";
 * 		alert( QueryString.parse(location.search).name ); // baby
 * 或 	alert( QueryString.parse(url).name );	// baby
 *
 * [字典对象转query字符串]
 *		QueryString.stringify({cityid:2, cityname:"上海" });
 *		//>> "cityid=2&cityname=%E4%B8%8A%E6%B5%B7" // 默认使用 encodeURIComponent 编码
 *		// escape 编码
 *		QueryString.stringify({cityid:2, cityname:"上海" }, escape );
 *		//>> "cityid=2&cityname=%u4E0A%u6D77"
 */

/**
 * 从字符串中提取字段
 * @param <string> str , 要解析的字符串
 * @param <function> decoder=decodeURIComponent, 解码器
 *		默认使用 decodeURIComponent
 *		即url参数中被URI编码过的字符或中文能被转码为正常字符
 * @internal <dic> o , 仅内部使用
 * @returns <dic> o
 */
const parse = function(str, decoder, o){
	decoder = decoder || decodeURIComponent;
	o = {}; str = str.replace(/^.*\?/,"").split("#")[0];
	if(!str || !/\=/.test(str)) return o;
	str.split("&").forEach(function(fs){
		fs = fs.split("=");
		o[fs[0]] = decoder(fs[1]||"");
	});
	return o;
}
/**
 * 字典对象转为query string
 * @param <dic> obj , 字典对象
 * @param <function> encoder=encodeURIComponent , 编码
 * @internal <string> qs, internal
 * @returns	<string> qs, QueryString
 */
const fromObject = function(obj,encoder, qs){
	encoder = encoder || encodeURIComponent;
	qs = [];
	var v,k
	for(k in obj){
		v = obj[k];
		qs.push(k+"="+encoder(typeof v=="string"?v:JSON.stringify(v)));
	}
	return qs.join("&");
}
/**
 * @alias fromObject()
 * fromObject 别名
 */
const stringify = function(){
	return fromObject.apply(this, arguments);
}

const mergeUrl = function(url, qs, encoder){
	var base = url.split("?")[0]
	,	fragment = url.split("#")[1] || ""
	,	bq = parse(url)
	,	qs = typeof qs == "string"? parse(qs): qs;
	fragment = fragment?("#"+fragment):""
	for(var k in qs){
		bq[k] = qs[k];
	}
	return [base, stringify(bq, encoder)+fragment].join("?")
}

Object.defineProperty(exports, "parse", {
  enumerable: true,
  get: function () {
    return parse;
  }
});
Object.defineProperty(exports, "stringify", {
  enumerable: true,
  get: function () {
    return stringify;
  }
});
Object.defineProperty(exports, "mergeUrl", {
  enumerable: true,
  get: function () {
    return mergeUrl;
  }
});